package testbean;
     /*
   configuration du clavier utilise

                    P4    P5    P6    P7
                    C1    C2    C3    C4
                    |     |     |     |
        P3 L4  _____|1____|2____|3____|___

        P2 L3  _____|4____|5____|6____|___

        P1 L2  _____|7____|8____|9____|___

        P0 L1  _____|*____|0____|#____|___

        la colonne C4 n'est pas utilisee

          ecrire 0x70
          lecture ligne
          if (ligne[1] != MASQUELIGNES)          // si touche appuyée
          {                                      // détemination du code de la touche
            ecrire 0x0F
            lecture colonne

            code = (byte)(((byte)ligne[1]) | ((byte)colonne[1]));
          }
          else code = PASDAPPUI;

                                       ecriture  0111 0000
                                              &  0110 0111   touche 1
                                                 ---------
                                         ligne = 0110 0000

                                       ecriture  0000 1111
                                              &  0110 0111   touche 1
                                                 ---------
                                       colonne = 0000 0111

                 code touche = ligne | colonne = 0110 0111

   */
  /**
 *   configuration du clavier utilise port A PCF8474
 *
 *          C1    C2    C3    C4
 *  L1 _____|1____|2____|3____|a___ PA0    1  0  0  0  1  1  1  1  1  1  1  1  0  1  1  1
 *
 *  L2 _____|4____|5____|6____|b___ PA1    1  1  1  1  0  0  0  1  1  1  1  1  1  0  1  1
 *
 *  L3 _____|7____|8____|9____|c___ PA2    1  1  1  1  1  1  1  0  0  0  1  1  1  1  0  1
 *
 *  L4 _____|*____|0____|#____|d___ PA3    0  1  1  1  1  1  1  1  1  1  0  0  1  1  1  0
 *          |     |     |     |            ----------------------------------------------
 *          |_____|_____|_____|____ PA4    1  0  1  1  0  1  1  0  1  1  0  1  1  1  1  1
 *                |     |     |
 *                |_____|_____|____ PA5    0  1  0  1  1  0  1  1  0  1  1  1  1  1  1  1
 *                      |     |
 *                      | ____|____ PA6    1  1  1  0  1  1  0  1  1  0  1  0  1  1  1  1
 *                            |
 *                            |____ PA7    1  1  1  1  1  1  1  1  1  1  1  1  0  0  0  0
 *                                         -----------------------------------------------
 *                                         0  1  2  3  4  5  6  7  8  9  *  #  a  b  c  d
 *  codes hexa                             D7 EE DE BE ED DD BD EB DB BB E7 B7 7E 7D 7B 77
 *  0..#    clavier 3 X 4
 *  a =     presence carte a puce
 *  b =     appel gardien
 *  c et d  non utilises
*/
import beanclavier.SimClavier;

public final class Clavier extends Thread
{
   private static final byte NBRETOUCHES    = (byte)16;
   private static final byte PASDAPPUI      = (byte)0xFF;
   private static final byte MASQUELIGNES   = (byte)0xF0;   // 0xF0 pour clavier 16 touches
   private static final byte MASQUECOLONNES = (byte)0x0F;


 private byte codeGeoMem = PASDAPPUI;
 private boolean touchesRelachees = true; //memorisation de l'etat "touches relachees" pour valider un nouvel appui sur une touche
 private int adresseI2c = 0x22;
 SimClavier ecranClavier;


 public Clavier(SimClavier ecranClavier)
 {
    this.ecranClavier = ecranClavier;
    ecranClavier.setAdresseI2c(0x22);
    start();
 }



 /**
  *  scrutation du clavier par un timer (ScanThread) toutes les 10ms
  *  les touches apuyees sont detectees ici et placees dans un petit tampon
  *  on effectue 2 lectures pour se premunir des rebonds eventuels
  */
  public final void doTimer()
  {
     byte oldCodeGeo = codeGeoMem;
     byte codeGeo = scan();
     codeGeoMem = (byte)codeGeo;
     if (codeGeo == oldCodeGeo)
     {
         if(codeGeo != (byte)0xff)                        // si touche appuyee
         {
            if (touchesRelachees)
            {
                byte codeTouche = (byte)ValTouche((byte)codeGeo);
                System.out.println("touche appuyee: " + codeTouche);
            }
            touchesRelachees = false;
         }
         else
         {
             touchesRelachees = true;

         }
       }
       else System.out.println(Integer.toBinaryString(codeGeo & 0xff));
  }

  public final byte scan()
  {
     byte ligne;
     byte colonne;
     byte code = (byte)0xff;
     byte[] b = new byte[1];
     b[0] = MASQUELIGNES;                                   // lignes a 0
     ecranClavier.write(adresseI2c, b, 0, 1);               //ecriture port
     ecranClavier.read(adresseI2c, b, 0, 1);                // lecture port
     ligne = b[0];
     if (ligne != MASQUELIGNES)                             // si touche appuyée
     {                                                      // détermination du code de la touche
       b[0] = MASQUECOLONNES;                               // colonnes a 0
       ecranClavier.write(adresseI2c, b, 0, 1);             // ecriture port
       ecranClavier.read(adresseI2c, b, 0, 1);              // lecture port
       colonne = b[0];
       code = (byte)(((byte)ligne) | ((byte)colonne));      // concatenation lignes colonnes
     }
     return code;
}



/**
 *  transcodage
 *  code geographique -> code touche
 */
 private static byte ValTouche(final byte codeGeo)
 {
     byte[][] TableCodes = {  {(byte)0x00,(byte)0xD7}, // touche 0  V1
                              {(byte)0x01,(byte)0xEE}, // touche 1
                              {(byte)0x02,(byte)0xDE}, // touche 2
                              {(byte)0x03,(byte)0xBE}, // touche 3
                              {(byte)0x04,(byte)0xED}, // touche 4
                              {(byte)0x05,(byte)0xDD}, // touche 5
                              {(byte)0x06,(byte)0xBD}, // touche 6
                              {(byte)0x07,(byte)0xEB}, // touche 7
                              {(byte)0x08,(byte)0xDB}, // touche 8
                              {(byte)0x09,(byte)0xBB}, // touche 9
                              {(byte)0x0a,(byte)0xE7}, // touche *
                              {(byte)0x0b,(byte)0xB7}, // touche #
                              {(byte)0x0c,(byte)0x7E}, // nu
                              {(byte)0x0d,(byte)0x7D}, // utilisee pour simul carte retiree
                              {(byte)0x0e,(byte)0x7B}, // Appel Gardien
                              {(byte)0x0f,(byte)0x77}};  // Presence carte


    byte result = PASDAPPUI;
    for (int i = 0; i < NBRETOUCHES; i++)
    {
        if ((byte)TableCodes[i][1] == (byte)codeGeo)
        {
            result = (byte)TableCodes[i][0];
            break;
        }
    }
    return result;
 }


   public void run()
   {
      byte[] b = new byte[1];
      while (true)
      {
        try
        {
          Thread.currentThread().sleep(25);
        }
        catch (InterruptedException ie) {}
        doTimer();
      }
   }

}